package query;

import index.HashIndex;
import global.Minibase;
import global.RID;
import global.SearchKey;
import heap.*;
import parser.AST_Delete;
import relop.*;

/**
 * Execution plan for deleting tuples.
 */
class Delete implements Plan {

	/**
	 * Optimizes the plan, given the parsed query.
	 * 
	 * @throws QueryException if table doesn't exist or predicates are invalid
	 */
	protected String table_name;
	protected Predicate [][] predicates;
	protected Schema schema;

	public Delete(AST_Delete tree) throws QueryException {
		table_name = tree.getFileName();
		predicates = tree.getPredicates();
		schema = Minibase.SystemCatalog.getSchema(table_name);

		QueryCheck.tableExists(table_name);
	} // public Delete(AST_Delete tree) throws QueryException

	/**
	 * Executes the plan and prints applicable output.
	 */
	public void execute() {
		HeapFile hf = new HeapFile (table_name);
		HeapScan hs = hf.openScan();

		RID rid = new RID();
		byte []b;
		Tuple t;
		int row_deleted_count = 0;
		IndexDesc []idesc = Minibase.SystemCatalog.getIndexes(table_name);
		boolean table_has_index = (idesc.length == 0)? false : true;

		while (hs.hasNext()){
			b = hs.getNext(rid);
			t = new Tuple (schema, b);
			boolean eval = false;                   // done on based of OR operator, so its OK if any of predicate is true

			for (Predicate []arr : predicates) {
				// for inner loop, every predicate shud be satisfied.
				for (Predicate p : arr){
					eval = eval | p.evaluate(t);
					if (eval == true)				// check this
						break;
				}
				if (eval == false)
					break;
			}

			if (eval) {
				row_deleted_count++;
				if (table_has_index){
					for (IndexDesc id : idesc){
						// check Shruti
						HashIndex hi = new HashIndex(id.indexName);
						Object o = t.getField(id.columnName);
						SearchKey sk = new SearchKey (o);
						hi.deleteEntry(sk, rid);				// hashIndex
					}
				}
				hf.deleteRecord(rid);  		// heapfile
				Minibase.SystemCatalog.incrementTableCardinality(table_name, -1);	//TODO: test thsi
			}
		}

		// print the output message
		System.out.println(row_deleted_count + " rows affected. ");
		hs.close();

	} // public void execute()

} // class Delete implements Plan
